/*
 * Created on 15-Nov-2004
 * Created by Paul Gardner
 * Copyright (C) Azureus Software, Inc, All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 */

package org.gudy.azureus2.core3.download;

import java.io.File;
import java.util.List;
import java.util.Map;

import org.gudy.azureus2.core3.category.Category;
import org.gudy.azureus2.core3.disk.DiskManagerFileInfo;
import org.gudy.azureus2.core3.torrent.TOTorrent;
import org.gudy.azureus2.core3.util.IndentWriter;
import org.gudy.azureus2.plugins.download.Download;

import com.aelitis.azureus.core.util.LinkFileMap;

/**
 * @author parg
 */

public interface DownloadManagerState {
    public static final String AT_VERSION = "version";
    public static final String AT_CATEGORY = "category";
    public static final String AT_NETWORKS = "networks";
    public static final String AT_USER = "user";
    public static final String AT_PEER_SOURCES = "peersources";
    public static final String AT_PEER_SOURCES_DENIED = "peersourcesdenied";
    public static final String AT_TRACKER_CLIENT_EXTENSIONS = "trackerclientextensions";
    public static final String AT_FILE_LINKS_DEPRECATED = "filelinks";
    public static final String AT_FILE_LINKS2 = "filelinks2";
    public static final String AT_FILE_STORE_TYPES = "storetypes";
    public static final String AT_FILE_DOWNLOADED = "filedownloaded";
    public static final String AT_FLAGS = "flags";
    public static final String AT_PARAMETERS = "parameters";
    public static final String AT_DISPLAY_NAME = "displayname";
    public static final String AT_USER_COMMENT = "comment";
    public static final String AT_RELATIVE_SAVE_PATH = "relativepath";
    public static final String AT_SECRETS = "secrets";
    public static final String AT_RESUME_STATE = "resumecomplete";
    public static final String AT_PRIMARY_FILE = "primaryfile";
    public static final String AT_PRIMARY_FILE_IDX = "primaryfileidx";
    public static final String AT_TIME_SINCE_DOWNLOAD = "timesincedl";
    public static final String AT_TIME_SINCE_UPLOAD = "timesinceul";
    public static final String AT_AVAIL_BAD_TIME = "badavail";
    public static final String AT_TIME_STOPPED = "timestopped";
    public static final String AT_INCOMP_FILE_SUFFIX = "incompfilesuffix";
    public static final String AT_SCRAPE_CACHE = "scrapecache"; // long value, seeds in upper word, leechers in lower
    public static final String AT_REORDER_MIN_MB = "reordermb";
    public static final String AT_MD_INFO_DICT_SIZE = "mdinfodictsize";
    public static final String AT_FILE_OTHER_HASHES = "fileotherhashes";
    public static final String AT_CANONICAL_SD_DMAP = "canosavedir";
    public static final String AT_DND_SUBFOLDER = "dnd_sf";
    public static final String AT_PEAK_RECEIVE_RATE = "pkdo";
    public static final String AT_PEAK_SEND_RATE = "pkup";
    public static final String AT_DL_FILE_ALERTS = "df_alerts";
    public static final String AT_SHARE_RATIO_PROGRESS = "sr.prog"; // long: left word - timestamp in secs, right word sr in 1000ths
    public static final String AT_FILES_EXPANDED = "file.expand"; // boolean

    public static Object[][] ATTRIBUTE_DEFAULTS = { { AT_VERSION, new Integer(-1) }, { AT_TIME_SINCE_DOWNLOAD, new Integer(-1) },
            { AT_TIME_SINCE_UPLOAD, new Integer(-1) }, { AT_AVAIL_BAD_TIME, new Long(-1) }, { AT_SCRAPE_CACHE, new Long(-1) },
            { AT_REORDER_MIN_MB, new Integer(-1) }, { AT_SHARE_RATIO_PROGRESS, new Long(0) }, };

    public static final long FLAG_ONLY_EVER_SEEDED = Download.FLAG_ONLY_EVER_SEEDED;
    public static final long FLAG_SCAN_INCOMPLETE_PIECES = Download.FLAG_SCAN_INCOMPLETE_PIECES;
    public static final long FLAG_DISABLE_AUTO_FILE_MOVE = Download.FLAG_DISABLE_AUTO_FILE_MOVE;
    public static final long FLAG_MOVE_ON_COMPLETION_DONE = Download.FLAG_MOVE_ON_COMPLETION_DONE;
    public static final long FLAG_LOW_NOISE = Download.FLAG_LOW_NOISE;
    public static final long FLAG_ALLOW_PERMITTED_PEER_SOURCE_CHANGES = Download.FLAG_ALLOW_PERMITTED_PEER_SOURCE_CHANGES;
    public static final long FLAG_DO_NOT_DELETE_DATA_ON_REMOVE = Download.FLAG_DO_NOT_DELETE_DATA_ON_REMOVE;
    public static final long FLAG_FORCE_DIRECT_DELETE = Download.FLAG_FORCE_DIRECT_DELETE;
    public static final long FLAG_DISABLE_IP_FILTER = Download.FLAG_DISABLE_IP_FILTER;
    public static final long FLAG_METADATA_DOWNLOAD = Download.FLAG_METADATA_DOWNLOAD;

    public static final String PARAM_MAX_PEERS = "max.peers";
    public static final String PARAM_MAX_PEERS_WHEN_SEEDING = "max.peers.when.seeding";
    public static final String PARAM_MAX_PEERS_WHEN_SEEDING_ENABLED = "max.peers.when.seeding.enabled";
    public static final String PARAM_MAX_SEEDS = "max.seeds";
    public static final String PARAM_MAX_UPLOADS = "max.uploads";
    public static final String PARAM_MAX_UPLOADS_WHEN_SEEDING = "max.uploads.when.seeding";
    public static final String PARAM_MAX_UPLOADS_WHEN_SEEDING_ENABLED = "max.uploads.when.seeding.enabled";
    public static final String PARAM_STATS_COUNTED = "stats.counted";
    public static final String PARAM_DOWNLOAD_ADDED_TIME = "stats.download.added.time";
    public static final String PARAM_DOWNLOAD_COMPLETED_TIME = "stats.download.completed.time";
    public static final String PARAM_DOWNLOAD_FILE_COMPLETED_TIME = "stats.download.file.completed.time";
    public static final String PARAM_MAX_UPLOAD_WHEN_BUSY = "max.upload.when.busy";
    public static final String PARAM_DND_FLAGS = "dndflags";
    public static final String PARAM_RANDOM_SEED = "rand";
    public static final String PARAM_UPLOAD_PRIORITY = "up.pri";
    public static final String PARAM_MIN_SHARE_RATIO = "sr.min"; // in thousandths - 1000 = sr of 1.0
    public static final String PARAM_MAX_SHARE_RATIO = "sr.max"; // in thousandths - 1000 = sr of 1.0

    public static final int DEFAULT_MAX_UPLOADS = 4;
    public static final int MIN_MAX_UPLOADS = 2;
    public static final int DEFAULT_UPLOAD_PRIORITY = 0;

    public static Object[][] PARAMETERS = { { PARAM_MAX_PEERS, new Integer(0) }, { PARAM_MAX_PEERS_WHEN_SEEDING, new Integer(0) },
            { PARAM_MAX_PEERS_WHEN_SEEDING_ENABLED, new Boolean(false) }, { PARAM_MAX_SEEDS, new Integer(0) },
            { PARAM_MAX_UPLOADS, new Long(DEFAULT_MAX_UPLOADS) }, { PARAM_MAX_UPLOADS_WHEN_SEEDING, new Integer(DEFAULT_MAX_UPLOADS) },
            { PARAM_MAX_UPLOADS_WHEN_SEEDING_ENABLED, new Boolean(false) }, { PARAM_STATS_COUNTED, new Boolean(false) },
            { PARAM_DOWNLOAD_ADDED_TIME, new Long(0) }, { PARAM_DOWNLOAD_FILE_COMPLETED_TIME, new Long(0) },
            { PARAM_DOWNLOAD_COMPLETED_TIME, new Long(0) }, { PARAM_MAX_UPLOAD_WHEN_BUSY, new Long(0) }, { PARAM_DND_FLAGS, new Long(0) },
            { PARAM_RANDOM_SEED, new Long(0) }, { PARAM_UPLOAD_PRIORITY, new Integer(DEFAULT_UPLOAD_PRIORITY) },
            { PARAM_MIN_SHARE_RATIO, new Integer(0) }, { PARAM_MAX_SHARE_RATIO, new Integer(0) }, };

    // current implementation of file links is too memory inefficient for a large number of files, disable these features
    // for huge torrents until this can be fixed :(

    public static final int MAX_FILES_FOR_INCOMPLETE_AND_DND_LINKAGE = 2048;

    public TOTorrent getTorrent();

    public DownloadManager getDownloadManager();

    public File getStateFile();

    public void setFlag(long flag, boolean set);

    public boolean getFlag(long flag);

    public long getFlags();

    /**
     * Reset to default value
     * 
     * @param name
     */

    public void setParameterDefault(String name);

    public int getIntParameter(String name);

    public void setIntParameter(String name, int value);

    public long getLongParameter(String name);

    public void setLongParameter(String name, long value);

    public boolean getBooleanParameter(String name);

    public void setBooleanParameter(String name, boolean value);

    public void clearResumeData();

    public Map getResumeData();

    public void setResumeData(Map data);

    public boolean isResumeDataComplete();

    public void clearTrackerResponseCache();

    public Map getTrackerResponseCache();

    public void setTrackerResponseCache(Map value);

    public Category getCategory();

    public void setCategory(Category cat);

    public String getDisplayName();

    public void setDisplayName(String name);

    public String getUserComment();

    public void setUserComment(String name);

    public String getRelativeSavePath();

    public void setPrimaryFile(DiskManagerFileInfo dmfi);

    public DiskManagerFileInfo getPrimaryFile();

    public String getTrackerClientExtensions();

    public void setTrackerClientExtensions(String value);

    public String[] // from AENetworkClassifier constants
            getNetworks();

    public boolean isNetworkEnabled(String network); // from AENetworkClassifier constants

    public void setNetworks(String[] networks); // from AENetworkClassifier constants

    public void setNetworkEnabled(String network, // from AENetworkClassifier constants
            boolean enabled);

    public String[] // from PEPeerSource constants
            getPeerSources();

    public boolean isPeerSourcePermitted(String peerSource);

    public void setPeerSourcePermitted(String peerSource, boolean permitted);

    public boolean isPeerSourceEnabled(String peerSource); // from PEPeerSource constants

    public void setPeerSources(String[] sources); // from PEPeerSource constants

    public void setPeerSourceEnabled(String source, // from PEPeerSource constants
            boolean enabled);

    // file links

    public void setFileLink(int source_index, File link_source, File link_destination);

    public void setFileLinks(List<Integer> source_indexes, List<File> link_sources, List<File> link_destinations);

    public void clearFileLinks();

    public File getFileLink(int source_index, File link_source);

    /**
     * returns a File -> File map of the defined links (empty if no links)
     * 
     * @return
     */

    public LinkFileMap getFileLinks();

    /**
     * @return
     */
    boolean isOurContent();

    // General access - make sure you use an AT_ value defined above when calling
    // these methods.
    public void setAttribute(String name, String value);

    public String getAttribute(String name);

    public void setMapAttribute(String name, Map value);

    public Map getMapAttribute(String name);

    public void setListAttribute(String name, String[] values);

    public String[] getListAttribute(String name);

    public String getListAttribute(String name, int idx);

    public void setIntAttribute(String name, int value);

    public int getIntAttribute(String name);

    public void setLongAttribute(String name, long value);

    public long getLongAttribute(String name);

    public void setBooleanAttribute(String name, boolean value);

    public boolean getBooleanAttribute(String name);

    public boolean hasAttribute(String name);

    public void setActive(boolean active);

    public void discardFluff();

    public void save();

    public boolean exportState(File target_dir);

    /**
     * deletes the saved state
     */

    public void delete();

    public void addListener(DownloadManagerStateListener l);

    public void removeListener(DownloadManagerStateListener l);

    /**
     * @param name
     * @return
     */
    boolean parameterExists(String name);

    public void generateEvidence(IndentWriter writer);

    public void dump(IndentWriter writer);

    /**
     * This method should only be invoked in matching try-finally pairs. If it is invoked with true multiple times it must be invoked with false the
     * equal amount of times to reallow state writes
     * 
     * @param suppress
     *            when set to true prevents flushing of the state/increments the internal nesting counter, decrements/allows flush otherwise
     */
    public void suppressStateSave(boolean suppress);

    public void addListener(DownloadManagerStateAttributeListener l, String attribute, int event_type);

    public void removeListener(DownloadManagerStateAttributeListener l, String attribute, int event_type);
}
